/**
 * Copyright (c) 2004-2015 All Rights Reserved.
 */
package com.zbest.common.lang.http;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.security.KeyStore;

import javax.net.ssl.SSLContext;

import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.HttpRequestRetryHandler;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.protocol.HttpContext;
import org.apache.http.ssl.SSLContexts;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 
 *
 * @author czhou3306@gmail.com
 * @version $Id: HttpClientTemplate.java, v0.1 2015年7月23日 下午12:51:06 czhou3306@gmail.com Exp $
 */
public class HttpClientTemplate {

    private static final Logger logger = LoggerFactory.getLogger(HttpClientTemplate.class);

    //生成一个默认的client，连接超时10s，读写超时10s，不重试
    private CloseableHttpClient client;

    /**
     * 构造器
     */
    public HttpClientTemplate() {
        client = HttpClients
            .custom()
            .setDefaultRequestConfig(
                RequestConfig.custom().setSocketTimeout(1000).setConnectTimeout(1000).build())
            .setRetryHandler(new HttpRequestRetryHandler() {

                @Override
                public boolean retryRequest(IOException exception, int executionCount,
                                            HttpContext context) {
                    return false;
                }
            }).build();
    }

    /**
     * 构造器
     */
    public HttpClientTemplate(byte[] certBytes, String password) {
        try {
            KeyStore keyStore = KeyStore.getInstance("PKCS12");
            InputStream certStream = new ByteArrayInputStream(certBytes);

            keyStore.load(certStream, password.toCharArray());//设置证书密码
            SSLContext sslcontext = SSLContexts.custom()
                .loadKeyMaterial(keyStore, password.toCharArray()).build();

            SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslcontext,
                new String[] { "TLSv1" }, null,
                SSLConnectionSocketFactory.getDefaultHostnameVerifier());

            client = HttpClients
                .custom()
                .setDefaultRequestConfig(
                    RequestConfig.custom().setSocketTimeout(1000).setConnectTimeout(1000).build())
                .setRetryHandler(new HttpRequestRetryHandler() {

                    @Override
                    public boolean retryRequest(IOException exception, int executionCount,
                                                HttpContext context) {
                        return false;
                    }
                }).setSSLSocketFactory(sslsf).build();

        } catch (Exception e) {
            logger.error("初始化异常", e);
            throw new RuntimeException(e);
        }
    }

    /**
     * 发起http get请求
     * 
     * @param url
     * @param charset
     * @return
     */
    public String get(String url, String charset) {

        HttpGet httpGet = null;
        HttpResponse response = null;
        try {
            httpGet = new HttpGet(url);
            httpGet.setHeader("Connection", "close");
            response = client.execute(httpGet);

            int statusCode = response.getStatusLine().getStatusCode();
            if (statusCode != HttpStatus.SC_OK) {
                throw new Exception("get异常");
            }

            String responseText = EntityUtils.toString(response.getEntity(), charset);
            logger.info("get结果responseText=" + responseText);

            return responseText;
        } catch (Exception e) {
            logger.error("http请求异常url=" + url, e);
            throw new RuntimeException(e);
        } finally {
            if (httpGet != null) {
                httpGet.releaseConnection();
            }
        }
    }

    /**
     * 发起post请求，
     * 
     * @param url 请求的地址
     * @param postData 以RequestEntity的形式传递
     * @param charset 字符集
     * @return
     */
    public String post(String url, String postData, String charset) {

        HttpPost httpPost = null;
        HttpResponse response = null;
        try {
            httpPost = new HttpPost(url);
            httpPost.setHeader("Connection", "close");
            httpPost.setEntity(new StringEntity(postData, charset));

            response = client.execute(httpPost);
            if (response.getStatusLine().getStatusCode() != 200) {
                throw new Exception("post异常");
            }

            String responseText = EntityUtils.toString(response.getEntity(), charset);

            logger.info("post结果responseText=" + responseText);
            return responseText;

        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            //client.getConnectionManager().closeIdleConnections(0, TimeUnit.SECONDS);
            if (httpPost != null) {
                httpPost.releaseConnection();
            }
        }
    }

}
